<?php

if (!function_exists('preprocess')) {

    function preprocess($raw)
    {
        $result = [];

        $result['code'] = 0;
        $result['data']['list'] = $raw['data'];
        $result['data']['pagination'] = [
            'current' => $raw['current_page'],
            'pageSize' => $raw['per_page'],
            'total' => $raw['total'],
        ];
        $result['msg'] = '';

        return $result;
    }

}

if (!function_exists('error')) {

    function error($raw)
    {
        $result = [];

        foreach ($raw as $key => $value) {
            $result[$key] = $value[0];
        }
        return $result;
    }

    function merge($old, $new)
    {
        return array_merge($old, $new);
    }

}

if (!function_exists('getRandomString')) {

    //获取字母数字随机数
    function getRandomString($len, $chars = null)
    {
        if (is_null($chars)) {
            $chars = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789";
        }
        mt_srand(10000000 * (double)microtime());
        for ($i = 0, $str = '', $lc = strlen($chars) - 1; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $lc)];
        }
        return $str;
    }

}

if (!function_exists('uuid')) {

    /**
     * Generate name based md5 UUID (version 3).
     * @example '7e57d004-2b97-0e7a-b45f-5387367791cd'
     */
    function uuid()
    {
        // fix for compatibility with 32bit architecture; seed range restricted to 62bit
        $seed = mt_rand(0, 2147483647) . '#' . mt_rand(0, 2147483647);

        // Hash the seed and convert to a byte array
        $val = md5($seed, true);
        $byte = array_values(unpack('C16', $val));

        // extract fields from byte array
        $tLo = ($byte[0] << 24) | ($byte[1] << 16) | ($byte[2] << 8) | $byte[3];
        $tMi = ($byte[4] << 8) | $byte[5];
        $tHi = ($byte[6] << 8) | $byte[7];
        $csLo = $byte[9];
        $csHi = $byte[8] & 0x3f | (1 << 7);

        // correct byte order for big edian architecture
        if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
            $tLo = (($tLo & 0x000000ff) << 24) | (($tLo & 0x0000ff00) << 8) | (($tLo & 0x00ff0000) >> 8) | (($tLo & 0xff000000) >> 24);
            $tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8);
            $tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8);
        }

        // apply version number
        $tHi &= 0x0fff;
        $tHi |= (3 << 12);

        // cast to string
        $uuid = sprintf(
            '%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x', $tLo, $tMi, $tHi, $csHi, $csLo, $byte[10], $byte[11], $byte[12], $byte[13], $byte[14], $byte[15]
        );

        return $uuid;
    }
}


/**
 * 获取客户端浏览器信息
 */
if (!function_exists('getAgentModel')) {

    function getAgentModel()
    {
        $user_agent = $_SERVER['HTTP_USER_AGENT'];

        $data = [
            'msie' => [
                ['MSIE 9.0', 'Internet Explorer 9.0'],
                ['MSIE 8.0', 'Internet Explorer 8.0'],
                ['MSIE 7.0', 'Internet Explorer 7.0'],
                ['MSIE 6.0', 'Internet Explorer 6.0'],
            ],
            'browser' => [
                'Firefox', 'Chrome', 'Opera', '360SE', 'MicroMessage', 'Safari',
            ],
            'mobile' => [
                "iPhone" => ["iPhone"],
                '联想' => ["Lenovo"],
                '三星' => ["SAMSUNG", "Galaxy", "GT-", "SCH-", "SM-"],
                '华为' => ["Huawei", "Honor", "H60-", "H30-"],
                '小米' => ["MI-ONE", "MI 1S", "MI 2", "MI 3", "MI 4", "MI-4"],
                '红米' => ["HM NOTE", "HM201"],
                '酷派' => ["Coolpad", "8190Q", "5910",],
                '中兴' => ["ZTE", "X9180", "N9180", "U9180"],
                'OPPO' => ["OPPO", "X9007", "X907", "X909", "R831S", "R827T", "R821T", "R2017"],
                'HTC' => ["HTC", "Desire"],
                'vivo' => ["vivo"],
                '天语' => ["K-Touch"],
                '努比亚' => ["Nubia", "NX50", "NX40"],
                '魅族' => ["M045", "M032", "M355"],
                '朵唯' => ["DOOV"],
                '基伍' => ["GFIVE"],
                '金立' => ["Gionee", "GN"],
                '海信' => ["HS-U", "HS-E"],
                '诺基亚' => ["Nokia"],
            ],
        ];

        if (stripos($user_agent, 'MSIE') !== false) {
            $msieActual = array_reduce($data['msie'], function ($resMsie, $msie) use ($user_agent) {
                if (stripos($user_agent, $msie[0]) !== false) {
                    $resMsie = $msie[1];
                }
                return $resMsie;
            });

            if (!empty($msieActual)) {
                return $msieActual;
            }
        }

        if (isMobile()) {
            foreach ($data['mobile'] as $key => $mobile) {
                $keyActual = array_reduce($mobile, function ($resMobile, $v) use ($user_agent, $key) {
                    if (stripos($user_agent, $v) !== false) {
                        $resMobile = $key;
                    }
                    return $resMobile;
                });
            }

            if (!empty($keyActual)) {
                return $keyActual;
            }
        }

        $browserActual = array_reduce($data['browser'], function ($resBrowser, $browser) use ($user_agent) {
            if (stripos($user_agent, $browser) !== false) {
                $resBrowser[] = $browser;
            }
            return $resBrowser;
        });

        if (!empty($browserActual)) {
            return $browserActual[0];
        }
        return 'other';
    }

}


/**
 * 判断是否手机访问,火狐模拟器返回fasle，chrome模拟器返回true
 * 火狐需要在模拟器右边的“自定义 User Agent”包含下面代码判断的关键字才行，比如:Mozilla/5.0 android,或直接android
 * @return boolean
 */
if (!function_exists('isMobile')) {

    function isMobile()
    {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
            return true;
        }
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset($_SERVER['HTTP_VIA'])) {
            // 找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
        }
        // 判断手机发送的客户端标志,兼容性有待提高,把常见的类型放到前面
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = [
                'android',
                'iphone',
                'samsung',
                'ucweb',
                'wap',
                'mobile',
                'nokia',
                'sony',
                'ericsson',
                'mot',
                'htc',
                'sgh',
                'lg',
                'sharp',
                'sie-',
                'philips',
                'panasonic',
                'alcatel',
                'lenovo',
                'ipod',
                'blackberry',
                'meizu',
                'netfront',
                'symbian',
                'windowsce',
                'palm',
                'operamini',
                'operamobi',
                'openwave',
                'nexusone',
                'cldc',
                'midp',
            ];
            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
                return true;
            }
        }
        // 协议法，因为有可能不准确，放到最后判断
        if (isset($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }
        return false;
    }

}


/**
 * 获取PC操作系统信息
 */
if (!function_exists('getPcOs')) {

    function getPcOs()
    {
        $agent = $_SERVER['HTTP_USER_AGENT'];
        $os = false;

        $data = [
            'win' => [['/win/i', '/98/i', 'Windows 98'],
                ['/win/i', '/nt 6.0/i', 'Windows Vista'],
                ['/win/i', '/nt 6.1/i', 'Windows 7'],
                ['/win/i', '/nt 6.2/i', 'Windows 8'],
                ['/win/i', '/nt 10.0/i', 'Windows 10'],
                ['/win/i', '/nt 5.1/i', 'Windows XP'],
                ['/win/i', '/nt 5/i', 'Windows 2000'],
                ['/win/i', '/nt/i', 'Windows NT'],
                ['/win/i', '/32/i', 'Windows 32'],
            ],
            'os' => [['/os/i', '/sun/i', 'SunOS'],
                ['/os/i', '/ibm/i', 'IBM OS/2'],
            ],
            'other' => [
                ['', '/PowerPC/i', 'PowerPC'],
                ['', '/AIX/i', 'AIX'],
                ['', '/HPUX/i', 'HPUX'],
                ['', '/NetBSD/i', 'NetBSD'],
                ['', '/BSD/i', 'BSD'],
                ['', '/OSF1/i', 'OSF1'],
                ['', '/IRIX/i', 'IRIX'],
                ['', '/FreeBSD/i', 'FreeBSD'],
                ['', '/teleport/i', 'teleport'],
                ['', '/flashget/i', 'flashget'],
                ['', '/webzip/i', 'webzip'],
                ['', '/offline/i', 'offline'],
                ['', '/Linux/i', 'Linux'],
                ['', '/unix/i', 'Unix'],
            ],
            'especially' => ['/PC/i', '/Mac/i', 'Macintosh'],
        ];

        if (preg_match('/win/i', $agent)) {
            $win = checkArrayReduceValue($data['win'], $agent);
            if (!empty($win)) {
                return $win;
            }
        }

        if (preg_match('/os/i', $agent)) {
            $os = checkArrayReduceValue($data['os'], $agent);
            if (!empty($os)) {
                return $os;
            }
        }

        if (preg_match('/PC/i', $agent)) {
            if (preg_match('/Mac/i', $agent)) {
                return $data['especially'][2];
            }
        }

        $other = checkArrayReduceValue($data['other'], $agent);
        if (!empty($other)) {
            return $other;
        }

        return '未知操作系统';
    }

}


/**
 * 获取手机系统
 */
if (!function_exists('getMobileOs')) {

    function getMobileOs()
    {
        $ua = $_SERVER['HTTP_USER_AGENT'];
        if (strpos($ua, 'Android') !== false) {//strpos()定位出第一次出现字符串的位置，这里定位为0
            preg_match("/(?<=Android )[\d\.]{1,}/", $ua, $version);
            return 'Android OS_Version:' . $version[0];
        }
        if (strpos($ua, 'iPhone') !== false) {
            preg_match("/(?<=CPU iPhone OS )[\d\_]{1,}/", $ua, $version);
            return 'iPhone OS_Version:' . str_replace('_', '.', $version[0]);
        }
        if (strpos($ua, 'iPad') !== false) {
            preg_match("/(?<=CPU OS )[\d\_]{1,}/", $ua, $version);
            return 'iPad OS_Version:' . str_replace('_', '.', $version[0]);
        }
    }

}

/**
 * 二维数组转移为检测一维数组值是否含有特有字符串
 */
if (!function_exists('checkArrayReduceValue')) {

    function checkArrayReduceValue($data, $agent)
    {
        $otherActual = array_reduce($data, function ($result, $other) use ($agent) {
            if (preg_match($other[1], $agent)) {
                return $other[2];
            }
        });

        if (!empty($otherActual)) {
            return $otherActual;
        }

        return null;
    }

}

/**
 * 获得用户的真实IP地址
 *
 * @access  public
 * @return  string
 */
if (!function_exists('real_ip')) {

    function real_ip()
    {
        static $realip = NULL;

        if ($realip !== NULL) {
            return $realip;
        }

        if (isset($_SERVER)) {

            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
                foreach ($arr AS $ip) {

                    $ip = trim($ip);

                    if ($ip != 'unknown') {
                        $realip = $ip;
                        break;
                    }
                }
            } else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $realip = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                if (isset($_SERVER['REMOTE_ADDR'])) {
                    $realip = $_SERVER['REMOTE_ADDR'];
                } else {
                    $realip = '0.0.0.0';
                }
            }
        } else {

            if (getenv('HTTP_X_FORWARDED_FOR')) {

                $realip = getenv('HTTP_X_FORWARDED_FOR');
            } else if (getenv('HTTP_CLIENT_IP')) {

                $realip = getenv('HTTP_CLIENT_IP');
            } else {
                $realip = getenv('REMOTE_ADDR');
            }
        }

        preg_match("/[\d\.]{7,15}/", $realip, $onlineip);

        $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';

        return $realip;
    }

}

/**
 * 获取指定时间之间的月份
 */
if (!function_exists('showMonthRange')) {
    function showMonthRange($start, $end)
    {
        $end = date('Ym', strtotime($end)); // 转换为月
        $range = [];
        $i = 0;
        do {
            $month = date('Ym', strtotime($start . ' + ' . $i . ' month'));
            //echo $i . ':' . $month . '<br>';
            $range[] = $month;
            $i++;
        } while ($month < $end);

        return $range;
    }
}


/**
 * 判断姓名是否全是中文
 */
if (!function_exists('isAllChinese')) {
    function isAllChinese($str)
    {
        //新疆等少数民族可能有·
        if (strpos($str, '·')) {
            //将·去掉，看看剩下的是不是都是中文
            $str = str_replace("·", '', $str);
            if (preg_match('/^[\x7f-\xff]+$/', $str)) {
                return true;//全是中文
            } else {
                return false;//不全是中文
            }
        } else {
            if (preg_match('/^[\x7f-\xff]+$/', $str)) {
                return true;//全是中文
            } else {
                return false;//不全是中文
            }
        }
    }

}